package com.ibeeking.found.upms.s.rest.service.impl;

import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.upms.s.rest.service.IShopRoleService;
import com.ibeeking.found.upms.s.rest.service.IShopUserRelationService;
import com.ibeeking.found.upms.s.rest.service.IShopUserRoleService;
import com.ibeeking.found.upms.service.common.bo.ShopUserRelationBO;
import com.ibeeking.found.upms.service.common.bo.ShopUserRoleBO;
import com.ibeeking.found.upms.service.common.dos.ShopUserRoleDO;
import com.ibeeking.found.upms.service.common.param.RoleUserParam;
import com.ibeeking.found.upms.service.common.param.UserRoleParam;
import com.ibeeking.found.upms.service.mapper.ShopUserRoleMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName ShopUserRoleServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-02-22 9:32
 **/
@Service
public class ShopUserRoleServiceImpl implements IShopUserRoleService {

    @Resource
    private IShopRoleService roleServiceImpl;
    @Resource
    private ShopUserRoleMapper shopUserRoleMapper;
    @Resource
    private IShopUserRelationService shopShopUserServiceImpl;

    @Override
    public List<ShopUserRoleBO> queryRoleIdsByUserId(Long shopId, Long userId) {
        List<ShopUserRoleDO> shopUserRoleDos = shopUserRoleMapper.selectList(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                .eq(ShopUserRoleDO::getShopId, shopId)
                .eq(ShopUserRoleDO::getUserId, userId)
        );
        if (Collections3.isEmpty(shopUserRoleDos)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(shopUserRoleDos, ShopUserRoleBO.class);
    }

    @Override
    public List<ShopUserRoleBO> queryUserRoleByRoleIds(Long shopId, List<Long> roleIds) {
        if (Collections3.isEmpty(roleIds)) {
            return Collections3.emptyList();
        }
        List<ShopUserRoleDO> shopUserRoleDos = shopUserRoleMapper.selectList(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                .eq(ShopUserRoleDO::getShopId, shopId)
                .in(ShopUserRoleDO::getRoleId, roleIds)
        );
        if (Collections3.isEmpty(shopUserRoleDos)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(shopUserRoleDos, ShopUserRoleBO.class);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean modifyUserRoleByUserId(CurrentUser currentUser, UserRoleParam userRoleParam) {
        if (currentUser.getId().equals(userRoleParam.getUserId())) {
            throw new BusinessException("禁止修改自己的角色");
        }
        ShopUserRelationBO shopUserRelationBO = shopShopUserServiceImpl.selectByUserId(currentUser.getCurrentShop().getShopId(), userRoleParam.getUserId());
        if (null == shopUserRelationBO) {
            throw new BusinessException("员工不存在");
        }
        if (PublishStatusEnum.DISABLE.getValue().equals(shopUserRelationBO.getLock()) || PublishStatusEnum.DISABLE.getValue().equals(shopUserRelationBO.getJob())) {
            throw new BusinessException("用户已离职或被锁定，禁止配置角色");
        }

        Long administratorId = roleServiceImpl.selectAdministratorId();
        //查询超级管理员对应的用户id
        List<ShopUserRoleBO> shopUserRoleBos1 = queryUserRoleByRoleIds(currentUser.getCurrentShop().getShopId(), Arrays.asList(administratorId));
        shopUserRoleMapper.delete(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                .eq(ShopUserRoleDO::getShopId, currentUser.getCurrentShop().getShopId())
                .eq(ShopUserRoleDO::getUserId, userRoleParam.getUserId()));

        // 1. 查询现有用户角色id列表
        List<ShopUserRoleBO> shopUserRoleBos = queryRoleIdsByUserId(currentUser.getCurrentShop().getShopId(), userRoleParam.getUserId());
        List<Long> haveRoleIds = shopUserRoleBos.parallelStream().map(ShopUserRoleBO::getRoleId).collect(Collectors.toList());
        if (null == userRoleParam.getRoleIds() || 0 == userRoleParam.getRoleIds().length) {
            if (haveRoleIds.contains(administratorId)) {
                throw new BusinessException("超级管理员至少要有一位");
            }
            return true;
        }
        List<Long> paramIds = Arrays.asList(userRoleParam.getRoleIds());

        if (paramIds.contains(administratorId)) {
            if (Collections3.isEmpty(shopUserRoleBos1)) {
                throw new BusinessException("非超级管理员禁止配置超级管理员角色");
            } else {
                Long userId = shopUserRoleBos1.get(0).getUserId();
                if (userId.equals(userRoleParam.getUserId()) && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                }

                //删除超级管理员关联用户
                shopUserRoleMapper.delete(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                        .eq(ShopUserRoleDO::getShopId, currentUser.getCurrentShop().getShopId())
                        .eq(ShopUserRoleDO::getRoleId, administratorId));
                paramIds = new ArrayList<>();
                paramIds.add(administratorId);
            }
        } else {
            if (!Collections3.isEmpty(shopUserRoleBos1)) {
                Long userId = shopUserRoleBos1.get(0).getUserId();
                if (userId.equals(userRoleParam.getUserId()) && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                }
            }
        }
        //新增关系
        List<ShopUserRoleDO> saves = new ArrayList<>();
        paramIds.stream().forEach(key -> {
            ShopUserRoleDO userRoleDO = new ShopUserRoleDO();
            userRoleDO.setShopId(currentUser.getCurrentShop().getShopId());
            userRoleDO.setRoleId(key);
            userRoleDO.setUserId(userRoleParam.getUserId());
            saves.add(userRoleDO);
        });
        // 新增关系
        shopUserRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public Boolean modifyUserRoleByRoleId(CurrentUser currentUser, RoleUserParam param) {
        //查询超级管理员对应的用户id
        Long administratorId = roleServiceImpl.selectAdministratorId();
        List<ShopUserRoleBO> shopUserRoleBos1 = queryUserRoleByRoleIds(currentUser.getCurrentShop().getShopId(), Arrays.asList(administratorId));
        shopUserRoleMapper.delete(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                .eq(ShopUserRoleDO::getShopId, currentUser.getCurrentShop().getShopId())
                .eq(ShopUserRoleDO::getRoleId, param.getRoleId()));
        if (null == param.getUserIds() || 0 == param.getUserIds().length) {
            if (param.getRoleId().equals(administratorId)) {
                throw new BusinessException("超级管理员至少选择一个用户");
            }
            return true;
        }
        List<Long> paramIds = Arrays.asList(param.getUserIds());
        if (param.getRoleId().equals(administratorId)) {
            if (paramIds.size() > 1) {
                throw new BusinessException("超级管理员至多选择一个用户");
            }
            if (Collections3.isEmpty(shopUserRoleBos1)) {
                throw new BusinessException("非超级管理员禁止配置超级管理员角色");
            } else {
                Long userId = shopUserRoleBos1.get(0).getUserId();
                if (paramIds.contains(userId) && !currentUser.getId().equals(userId)) {
                    if (!currentUser.getId().equals(userId)) {
                        throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                    }
                }
            }
        }
        //新增关系
        List<ShopUserRoleDO> saves = new ArrayList<>();
        paramIds.stream().forEach(key -> {
            ShopUserRoleDO userRoleDO = new ShopUserRoleDO();
            userRoleDO.setShopId(currentUser.getCurrentShop().getShopId());
            userRoleDO.setRoleId(param.getRoleId());
            userRoleDO.setUserId(key);
            saves.add(userRoleDO);
        });
        shopUserRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Override
    public List<ShopUserRoleBO> queryRoleIdsByUserIds(Long shopId, List<Long> userIds) {
        if (Collections3.isEmpty(userIds)) {
            return Collections3.emptyList();
        }
        List<ShopUserRoleDO> shopUserRoleDos = shopUserRoleMapper.selectList(new LambdaQueryWrapper<>(ShopUserRoleDO.class)
                .eq(ShopUserRoleDO::getShopId, shopId)
                .in(ShopUserRoleDO::getUserId, userIds)
        );
        return JsonUtils.jsonToList(shopUserRoleDos, ShopUserRoleBO.class);
    }
}
